package tazmania.entity;

import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.glu.gl2.GLUgl2;

import tazadum.engine.Entity;
import tazadum.engine.Interval;
import tazadum.engine.Signal;

public class SupG implements Entity {
	private final Signal signal;
	protected GLUgl2 glu = new GLUgl2();
	private final float verticesX[];
	private final float verticesY[];
	private final float verticesZ[];
	private final float verticesColor[];
	private static final int NUMBER_OF_VERTICES = 314;
	private final int distSignal;

	public SupG(final Signal signal, final int distSignal) {
		this.signal = signal;
		this.distSignal = distSignal;
		verticesX = new float[NUMBER_OF_VERTICES];
		verticesY = new float[NUMBER_OF_VERTICES];
		verticesZ = new float[NUMBER_OF_VERTICES];
		verticesColor = new float[NUMBER_OF_VERTICES];
	}

	@Override
	public void precalc(final GLAutoDrawable drawable, final float screenRatio) {
	}

	@Override
	public void update(final GLAutoDrawable drawable, final float globalTime, final float localTime, final float dt, final Interval interval) {
		final GL2 gl = drawable.getGL().getGL2();

		gl.glMatrixMode(GL2.GL_PROJECTION);
		gl.glPushMatrix();
		glu.gluPerspective(110, 1, 0.1f, 1000);

		gl.glMatrixMode(GL2.GL_MODELVIEW);
		gl.glPushMatrix();
		gl.glLoadIdentity();

		gl.glEnable(GL.GL_DEPTH_TEST);
		gl.glEnable(GL.GL_BLEND);
		gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);

		// Define shapes
		final float distortion = signal.channel(distSignal);
		final float time = localTime * 10 + (1 * distortion);
		double x = 0;
		double y = 0;
		double angle = localTime;
		for (int i = 0; i < NUMBER_OF_VERTICES; i++) {
			angle += .1;
			x = Math.sin(angle) * (Math.sin(time + i * .1764) * 2 + 3);
			y = Math.cos(angle * .786) * (Math.cos(time + i * .264) * 2 + 3);

			verticesX[i] = (float) x;
			verticesY[i] = (float) y;
			verticesZ[i] = -((i & 1) + i * .1f);

			verticesColor[i] = (float) Math.sin(time + i * 2 * 3.1415 / 10) * .5f + .5f;
		}

		float alpha = 1;
		if (localTime < 2) {
			alpha = localTime * 0.5f;
		} else if (globalTime >= interval.to() - 2) {
			alpha = 1 - (globalTime - (interval.to() - 2)) * .5f;
		}
		alpha *= 0.8f;
		gl.glRotatef(localTime * 10, 0, 0, 1);
		gl.glPolygonMode(GL.GL_FRONT_AND_BACK, GL2.GL_LINE);
		gl.glBegin(GL2.GL_TRIANGLE_STRIP);
		for (int i = 0; i < NUMBER_OF_VERTICES; i++) {
			{
				gl.glColor4f(verticesColor[i], verticesColor[i], verticesColor[i] * (1 - distortion), alpha);
				gl.glVertex3f(verticesX[i], verticesY[i], verticesZ[i]);
			}
		}
		gl.glEnd();

		gl.glDisable(GL.GL_DEPTH_TEST);
		gl.glDisable(GL.GL_BLEND);

		// gl.glMatrixMode(GL2.GL_MODELVIEW);
		gl.glPopMatrix();
		gl.glMatrixMode(GL2.GL_PROJECTION);
		gl.glPopMatrix();

	}

	@Override
	public void destroy(final GLAutoDrawable drawable) {
	}
}